﻿/*
 
    Copyright (c) 2010 Ralf Westphal <info@ralfw.de>
     
    This file is part of NZMQ, nzmq.codeplex.com
     
    NZMQ is free software; you can redistribute it and/or modify it under
    the terms of the Lesser GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
     
    NZMQ is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    Lesser GNU General Public License for more details.
     
    You should have received a copy of the Lesser GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.

*/
using System;
using nzmq.raw;

namespace nzmq
{
    public class NzmqBaseSocket : IDisposable
    {
        protected readonly LibzmqSocket _rawSocket;


        internal protected NzmqBaseSocket(LibzmqSocket rawSocket)
        {
            _rawSocket = rawSocket;
        }


        public string Identity
        {
            get { return _rawSocket.GetSockOptAsString(NzmqSocketOptions.Identity); }
            set { _rawSocket.SetSockOptAsString(NzmqSocketOptions.Identity, value); }
        }

        public long HighWaterMark
        {
            get { return _rawSocket.GetSockOptAsInt64(NzmqSocketOptions.HighWaterMarkForNumberOfMessages); }
            set { _rawSocket.SetSockOptAsIn64(NzmqSocketOptions.HighWaterMarkForNumberOfMessages, value); }
        }
        
        public long SwapSpace
        {
            get { return _rawSocket.GetSockOptAsInt64(NzmqSocketOptions.SwapSpaceSizeInBytes); }
            set { _rawSocket.SetSockOptAsIn64(NzmqSocketOptions.SwapSpaceSizeInBytes, value); }
        }


        public bool EndOfMultipartMessage
        {
            get { return _rawSocket.GetSockOptAsInt64(NzmqSocketOptions.ReceiveMore) == 0; }
        }


        public void Bind(string bindingAddress)
        {
            _rawSocket.Bind(bindingAddress);
        }

        public void Connect(string connectionAddress)
        {
            _rawSocket.Connect(connectionAddress);
        }


        internal protected void Send(object payload, bool isMultipart=false)
        {
            _rawSocket.Send(new NzmqMessage(payload).ToBytes(), isMultipart ? libzmq.SNDMORE : 0);
        }

        internal protected object Receive()
        {
            return NzmqMessage.FromBytes(_rawSocket.Recv()).Payload;
        }

        internal protected bool TryReceive(out object payload, bool blocking=true)
        {
            byte[] buffer;
            if (_rawSocket.TryRecv(out buffer, blocking ? 0 : libzmq.NOBLOCK))
            {
                payload = NzmqMessage.FromBytes(buffer).Payload;
                return true;
            }
            payload = null;
            return false;
        }

        
        internal LibzmqSocket RawSocket
        {
            get { return _rawSocket; }
        }


        public void Dispose()
        {
            _rawSocket.Dispose();
        }
    }
}